/**
 * 
 */
package com.search;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

import org.joy.analyzer.Hit;
import org.joy.analyzer.HitAnalyzer;
import org.joy.analyzer.html.HTMLDocument;
import org.joy.analyzer.html.ParseException;
import org.joy.analyzer.html.Utility;
import org.joy.nlp.HLWordSpliter;
import org.joy.nlp.WordSpliter;

import com.corpus.KeyWordSet;
import com.link.PageRankService;

/**
 * @author LvSaiHui {gurnfe@163.com}
 * @version 1.0 <br>
 *          Copyright (C), 2007-2008, ZJUT <br>
 *          This program is protected by copyright laws. <br>
 *          Program Name: Similarity.java <br>
 *          Date: 2009-2-18 <br>
 *          Description:
 */
public class Similarity {
	public static double scoreOnWebPageText(String url) throws ParseException,
			IOException {
		HTMLDocument doc = HTMLDocument.createHTMLDocument(url, Utility
				.getWebContent(url));
		return scoreOnWebPageText(url, doc);
	}

	public static double scoreOnWebPageText(String url, HTMLDocument doc)
			throws ParseException, IOException {
		WordSpliter w = new HLWordSpliter();
		HitAnalyzer a = new HitAnalyzer(doc, w);
		a.doAnalyze();
		int themeSize = KeyWordSet.Theme.size();
		double[][] weightArray = new double[2][themeSize];
		Hit[] hits = a.getHits().toArray(new Hit[0]);

		Iterator it = KeyWordSet.Theme.entrySet().iterator();
		int j = 0;
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			Object key = entry.getKey();
			String keyword = (String) key;
			Double val = (Double) entry.getValue();
			weightArray[0][j] = val;
			for (int i = 0; i < hits.length; i++) {

				if (keyword.equals(hits[i].getTerm())) {
					weightArray[1][j] = hits[i].getScore();
					// System.out.println(keyword+" : "+weightArray[0][j]+" : "+weightArray[1][j]);
					break;
				}

			}

			// System.out.println(keyword + " : " + weightArray[0][j] + " : "+
			// weightArray[1][j]);
			j++;
		}
		double[][] normalizedWeightArray = normalize(weightArray);
		// System.out.println("Begin to display the normalized Weight Array");
		// display(normalizedWeightArray);
		double returnValue = cosinSimilarity(normalizedWeightArray);
		// System.out.println("The similarity score of the page after normalized is :"+returnValue);
		// System.out.println("The similarity score of the page before normalized is :"+cosinSimilarity(weightArray));
		return returnValue;
	}

	public static double scoreBasedOnUrlText(String urlText) {
		double resultValue = 0;
		if (urlText != null && urlText.trim().length() > 0) {
			int themeSize = KeyWordSet.Theme.size();
			Iterator it = KeyWordSet.Theme.entrySet().iterator();
			double[][] weightArray = new double[2][themeSize];
			int j = 0;
			while (it.hasNext()) {
				Map.Entry entry = (Map.Entry) it.next();
				Object key = entry.getKey();
				String keyword = (String) key;
				Double val = (Double) entry.getValue();
				weightArray[0][j] = val;
				if (urlText.indexOf(keyword) >= 0) {
					weightArray[1][j] = val;
				} else {
					weightArray[1][j] = 0;
				}

				j++;
			}
			resultValue = cosinSimilarity(weightArray);
		}

		return resultValue;
	}

	public static double scoreOnPageRank(String url)  {
		double returnValue = 0.0;
		if (url != null && url.trim().length() > 0) {
			String domain = Utility.extractDomain(url);
			returnValue = PageRankService.getPR(domain)/20.0;

		}

		return returnValue;

	}

	public static double[][] normalize(double[][] weightArray) {
		// 对第2行根据最大作为基准,进行频比正则化
		double max = weightArray[1][0];
		for (int i = 0; i < weightArray[1].length; i++) {
			if (weightArray[1][i] > max) {
				max = weightArray[1][i];
			}
		}
		// System.out.println(max);
		if (max != 0) {
			for (int k = 0; k < weightArray[1].length; k++) {
				weightArray[1][k] = weightArray[1][k] / max;
			}
		}
		return weightArray;

	}

	public static double cosinSimilarity(double[][] array) {
		double retValue = 0.0;
		double numeratorSum = 0;
		double denominatorSum1 = 0;
		double denominatorSum2 = 0;
		for (int i = 0; i < array[0].length; i++) {
			numeratorSum += array[0][i] * array[1][i];
			denominatorSum1 += array[0][i] * array[0][i];
			denominatorSum2 += array[1][i] * array[1][i];
		}
		if (denominatorSum1 > 0 && denominatorSum2 > 0) {
			retValue = numeratorSum
					/ (Math.sqrt(denominatorSum1) * Math.sqrt(denominatorSum2));
		}

		return retValue;
	}

	public static void display(double[][] array) {
		for (int j = 0; j < array[0].length; j++) {
			System.out.println(array[0][j] + "  :  " + array[1][j]);
		}
	}

	/**
	 * @param args
	 * @throws IOException
	 * @throws ParseException
	 */
	public static void main(String[] args) throws ParseException, IOException {
		/*
		 * String urltext="信用价值"; String keyword="信用";
		 * System.out.println(urltext.indexOf(keyword));
		 */
		System.out.println("The similarity score of the page  is :"
				+ Similarity.scoreOnWebPageText("http://www.zjut.edu.cn/zjut/xyw/xxgk/zbxx.htm"));
	}

}
